package com.youhome.service.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.youhome.common.config.OSSConfig;
import com.youhome.common.exception.CustomException;
import com.youhome.common.response.ResultCode;
import com.youhome.service.mapper.BSendRecordMailGatherMapper;
import com.youhome.service.mapper.BSendRecordMailMapper;
import com.youhome.service.mapper.BTemplateMailMapper;
import com.youhome.service.model.*;
import com.youhome.service.response.Mail;
import com.youhome.service.response.Param;
import com.youhome.service.service.BCompanyService;
import com.youhome.service.service.BUserService;
import com.youhome.service.service.MailService;
import com.youhome.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by chen365 on 2017/12/7.
 */
@Service
public class MailServiceImpl implements MailService {
    @Autowired
    private OSSConfig ossConfig;
    @Autowired
    private BSendRecordMailMapper bSendRecordMailMapper;
    @Autowired
    private BTemplateMailMapper bTemplateMailMapper;
    @Autowired
    private BSendRecordMailGatherMapper bSendRecordMailGatherMapper;
    @Autowired
    private BCompanyService bCompanyService;

    /**
     * 单一发信
     *
     * @param accountName 发信地址
     * @param fromAlias   发信人昵称
     * @param mails       收件地址
     * @param subject     邮件主题
     * @param htmlBody    邮件正文
     */
    @Override
    public int SingleSendMail(Long userid, String accountName, String fromAlias, List<Mail> mails, String subject, String htmlBody) throws ServerException, ClientException {
        String accessKeyId = ossConfig.getAccessKeyId();
        String secret = ossConfig.getAccessKeySecret();

        // 如果是除杭州region外的其它region（如新加坡、澳洲Region），
        // 需要将下面的"cn-hangzhou"替换为"ap-southeast-1"、或"ap-southeast-2"。
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret);
        // 如果是除杭州region外的其它region（如新加坡region）， 需要做如下处理
        //try {
        //DefaultProfile.addEndpoint("dm.ap-southeast-1.aliyuncs.com", "ap-southeast-1", "Dm",  "dm.ap-southeast-1.aliyuncs.com");
        //} catch (ClientException e) {
        //e.printStackTrace();
        //}
        IAcsClient client = new DefaultAcsClient(profile);
        SingleSendMailRequest request = new SingleSendMailRequest();
        //request.setVersion("2017-06-22");// 如果是除杭州region外的其它region（如新加坡region）,必须指定为2017-06-22
        request.setAccountName(accountName); //管理控制台中配置的发信地址。
        request.setFromAlias(fromAlias); //发信人昵称,长度小于 15 个字符。
        request.setAddressType(1); //取值范围 0~1: 0 为随机账号；1 为发信地址。
        //request.setTagName("控制台创建的标签");
        request.setReplyToAddress(true); //使用管理控制台中配置的回信地址（状态必须是验证通过）
        request.setSubject(subject); //邮件主题

        BSendRecordMail bSendRecordMail = new BSendRecordMail();
        bSendRecordMail.setUserId(userid);
        bSendRecordMail.setAccountname(accountName);
        bSendRecordMail.setFromalias(fromAlias);
        bSendRecordMail.setCtime(new Date());
        bSendRecordMail.setStatus(1);
        bSendRecordMail.setSubject(subject);

        for (Mail mail : mails) {

            String new_htmlBody = htmlBody;

            String regex = "\\{[^\\}]*\\}";
            Pattern pattern = Pattern.compile(regex);
            Matcher match = pattern.matcher(new_htmlBody);
            while (match.find()) {
                List<Param> params = mail.getParams();
                for (Param param : params) {
                    new_htmlBody = new_htmlBody.replace("{" + param.getName() + "}", param.getValue());
                }
            }

            request.setToAddress(mail.getEmail()); //收件地址
            request.setHtmlBody(new_htmlBody); //邮件正文
            SingleSendMailResponse httpResponse = client.getAcsResponse(request);

            System.err.println("httpResponse:" + httpResponse.toString());

            bSendRecordMail.setToaddress(mail.getEmail());
            bSendRecordMail.setHtmlbody(new_htmlBody);
            bSendRecordMailMapper.insertSelective(bSendRecordMail);
        }

        return 1;
    }

    /**
     * 单一发信
     *
     * @param accountName 发信地址
     * @param fromAlias   发信人昵称
     * @param mails       收件地址
     * @param subject     邮件主题
     * @param htmlBody    邮件正文
     */
    @Override
    public int SingleSendMail(Long userid, String accountName, String fromAlias, String mails, String subject, String htmlBody) throws ServerException, ClientException {
        String accessKeyId = ossConfig.getAccessKeyId();
        String secret = ossConfig.getAccessKeySecret();

        // 如果是除杭州region外的其它region（如新加坡、澳洲Region），
        // 需要将下面的"cn-hangzhou"替换为"ap-southeast-1"、或"ap-southeast-2"。
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret);
        // 如果是除杭州region外的其它region（如新加坡region）， 需要做如下处理
        //try {
        //DefaultProfile.addEndpoint("dm.ap-southeast-1.aliyuncs.com", "ap-southeast-1", "Dm",  "dm.ap-southeast-1.aliyuncs.com");
        //} catch (ClientException e) {
        //e.printStackTrace();
        //}
        IAcsClient client = new DefaultAcsClient(profile);
        SingleSendMailRequest request = new SingleSendMailRequest();
        //request.setVersion("2017-06-22");// 如果是除杭州region外的其它region（如新加坡region）,必须指定为2017-06-22
        request.setAccountName(accountName); //管理控制台中配置的发信地址。
        request.setFromAlias(fromAlias); //发信人昵称,长度小于 15 个字符。
        request.setAddressType(1); //取值范围 0~1: 0 为随机账号；1 为发信地址。
        //request.setTagName("控制台创建的标签");
        request.setReplyToAddress(true); //使用管理控制台中配置的回信地址（状态必须是验证通过）
        request.setSubject(subject); //邮件主题


        request.setToAddress(mails); //收件地址
        request.setHtmlBody(htmlBody); //邮件正文
        SingleSendMailResponse httpResponse = client.getAcsResponse(request);

        System.err.println("httpResponse:" + httpResponse.toString());

        BSendRecordMail bSendRecordMail = new BSendRecordMail();
        bSendRecordMail.setUserId(userid);
        bSendRecordMail.setAccountname(accountName);
        bSendRecordMail.setFromalias(fromAlias);
        bSendRecordMail.setCtime(new Date());
        bSendRecordMail.setStatus(1);
        bSendRecordMail.setSubject(subject);
        String[] arr_mails = mails.split(",");
        for (String mail : arr_mails) {
            bSendRecordMail.setToaddress(mail);
            bSendRecordMail.setHtmlbody(htmlBody);
            bSendRecordMailMapper.insertSelective(bSendRecordMail);
        }

        return 1;
    }

    @Override
    public int SingleSendMail(Long userId, String accountName, String companyName, List<Mail> mails, Long tempId) throws ServerException, ClientException {
        String accessKeyId = ossConfig.getAccessKeyId();
        String secret = ossConfig.getAccessKeySecret();

        // 如果是除杭州region外的其它region（如新加坡、澳洲Region），
        // 需要将下面的"cn-hangzhou"替换为"ap-southeast-1"、或"ap-southeast-2"。
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret);
        // 如果是除杭州region外的其它region（如新加坡region）， 需要做如下处理
        //try {
        //DefaultProfile.addEndpoint("dm.ap-southeast-1.aliyuncs.com", "ap-southeast-1", "Dm",  "dm.ap-southeast-1.aliyuncs.com");
        //} catch (ClientException e) {
        //e.printStackTrace();
        //}

        BTemplateMail bTemplateMail = bTemplateMailMapper.selectByPrimaryKey(tempId);
        String subject = bTemplateMail.getTitle();
        String htmlBody = bTemplateMail.getTemplate();

        BSendRecordMailGatherWithBLOBs sendRecordMailGatherWithBLOBs = new BSendRecordMailGatherWithBLOBs();
        sendRecordMailGatherWithBLOBs.setUserId(userId);
        sendRecordMailGatherWithBLOBs.setTempId(bTemplateMail.getId());
        sendRecordMailGatherWithBLOBs.setTempName(bTemplateMail.getName());
        sendRecordMailGatherWithBLOBs.setTempTitle(bTemplateMail.getTitle());
        sendRecordMailGatherWithBLOBs.setTemplate(bTemplateMail.getTemplate());
        sendRecordMailGatherWithBLOBs.setCount(mails.size());
        sendRecordMailGatherWithBLOBs.setParam(JSON.toJSON(mails).toString());
        sendRecordMailGatherWithBLOBs.setCtime(new Date());

        bSendRecordMailGatherMapper.insertSelective(sendRecordMailGatherWithBLOBs);

        Long gatherId = sendRecordMailGatherWithBLOBs.getId();

        IAcsClient client = new DefaultAcsClient(profile);
        SingleSendMailRequest request = new SingleSendMailRequest();
        //request.setVersion("2017-06-22");// 如果是除杭州region外的其它region（如新加坡region）,必须指定为2017-06-22
        request.setAccountName(accountName); //管理控制台中配置的发信地址。
        request.setFromAlias(companyName); //发信人昵称,长度小于 15 个字符。
        request.setAddressType(1); //取值范围 0~1: 0 为随机账号；1 为发信地址。
        //request.setTagName("控制台创建的标签");
        request.setReplyToAddress(true); //使用管理控制台中配置的回信地址（状态必须是验证通过）
        request.setSubject(subject); //邮件主题

        BSendRecordMail bSendRecordMail = new BSendRecordMail();
        bSendRecordMail.setUserId(userId);
        bSendRecordMail.setAccountname(accountName);
        bSendRecordMail.setFromalias(companyName);
        bSendRecordMail.setCtime(new Date());
        bSendRecordMail.setStatus(1);
        bSendRecordMail.setSubject(subject);
        bSendRecordMail.setGatherId(gatherId);

        for (Mail mail : mails) {

            String template = htmlBody;
            //String regex = "\\{[^\\}]*\\}";
            String regex = "\\{\\{[^\\}]*\\}\\}";
            Pattern pattern = Pattern.compile(regex);
            Matcher match = pattern.matcher(template);

            String name =""; //收件人姓名
            while (match.find()) {
                List<Param> params = mail.getParams();
                for (Param param : params) {
                    if(param.getName().equals("name")){
                        name = param.getValue();
                    }
                    template = template.replace("{{" + param.getName() + "}}", param.getValue());
                }
            }
            request.setToAddress(mail.getEmail()); //收件地址
            request.setHtmlBody(template); //邮件正文
            SingleSendMailResponse httpResponse = client.getAcsResponse(request);

            System.err.println("httpResponse:" + httpResponse.toString());
            bSendRecordMail.setName(name);
            bSendRecordMail.setToaddress(mail.getEmail());
            bSendRecordMail.setHtmlbody(template);

            System.err.println("bSendRecordMail======>>>"+bSendRecordMail.toString());
            bSendRecordMailMapper.insertSelective(bSendRecordMail);
        }

        return 1;
    }

    @Override
    public void sendMail(Principal principal, Long tempId, String mails) throws CustomException {
        String accountName = "mail@service.mf-data.com";//发信地址
        //String fromAlias = "MX"; //发信人昵称
        //String toAddress = "chen365@yeah.net";   //收件地址
        //String subject = "2017-12推荐房源";    //邮件主题
        //String htmlBody = "<h1>推荐房源</h1>";    //邮件正文

        if (StringUtils.isEmpty(mails)) {
            throw  new CustomException(ResultCode.EMAIL_ADDRESS_CANNOT_BE_EMPTY);
        }


        Long userId = principal.getUser().getUserId();
        BCompany bCompany = bCompanyService.selectByUserId(userId);
        if (bCompany == null) {
            throw new CustomException(ResultCode.DATA_DOES_NOT_EXIST_OR_HAS_BEEN_DELETED);
        }
        String companyName = bCompany.getName();
        List<Mail> list = JsonUtils.json2List(mails, Mail.class);

        try {
            if (SingleSendMail(userId, accountName, companyName, list, tempId) == 0) {
                throw new CustomException(ResultCode.SUCCESS);
            } else {
                throw new CustomException(ResultCode.FAIL);
            }
        } catch (ClientException e) {
            e.printStackTrace();
            String errCode = e.getErrCode().toLowerCase();
            if (errCode.equals("InvalidMailAddress.NotFound".toLowerCase())) {    //发信地址不存在。
                throw new CustomException(ResultCode.INVALID_MAIL_ADDRESS_NOT_FOUND);
            } else if (errCode.equals("InvalidMailAddressStatus.Malformed".toLowerCase())) {    //发信地址状态不正确 。
                throw new CustomException(ResultCode.INVALID_MAIL_ADDRESS_STATUS_MAL_FORMED);
            } else if (errCode.equals("InvalidToAddress".toLowerCase())) {    //目标地址不正确。
                throw new CustomException(ResultCode.INVALID_TO_ADDRESS);
            } else if (errCode.equals("InvalidBody".toLowerCase())) {    //邮件正文不正确。textBody 或 htmlBody 不能同时为空。
                throw new CustomException(ResultCode.INVALID_BODY);
            } else if (errCode.equals("InvalidSendMail.Spam".toLowerCase())) {    //本次发送操作被反垃圾系统检测为垃圾邮件，禁止发送。请仔细检查邮件内容和域名状态等。
                throw new CustomException(ResultCode.INVALID_SEND_MAIL_SPAM);
            } else if (errCode.equals("InvalidSubject.Malformed".toLowerCase())) {    //邮件主题限制在 100 个字符以内。
                throw new CustomException(ResultCode.INVALID_SUBJECT_MAL_FORMED);
            } else if (errCode.equals("InvalidMailAddressDomain.Malformed".toLowerCase())) {    //发信地址的域名状态不正确，请检查 MX、SPF 配置是否正确。
                throw new CustomException(ResultCode.INVALID_MAIL_ADDRESS_DOMAIN_MAL_FORMED);
            } else if (errCode.equals("InvalidFromALias.Malformed".toLowerCase())) {    //发信人昵称不正确，请检查发信人昵称是否正确，长度应小于 15 个字符。
                throw new CustomException(ResultCode.INVALID_FROM_ALIAS_MAL_FORMED);
            }
        }
        throw new CustomException(ResultCode.FAIL);
    }
}
